package com.ltmonitor.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ltmonitor.dao.IGPSRealDataDao;
import com.ltmonitor.dao.IVehicleDataDao;
import com.ltmonitor.dao.IVehicleInfoModifyRecordDao;
import com.ltmonitor.entity.Department;
import com.ltmonitor.entity.GPSRealData;
import com.ltmonitor.entity.VehicleData;
import com.ltmonitor.entity.VehicleInfoModifyRecord;
import com.ltmonitor.service.IDepartmentService;
import com.ltmonitor.service.IVehicleDataService;

@Service("vehicleDataService")
@Transactional
public class VehicleDataService extends BaseService<Long, VehicleData>
		implements IVehicleDataService {

	@Autowired
	private IVehicleDataDao vehicleDataDao;

	@Autowired
	private IVehicleInfoModifyRecordDao vehicleInfoModifyRecordDao;

	@Autowired
	private IGPSRealDataDao gpsRealDataDao;

	@Autowired
	private IDepartmentService departmentService;

	protected Logger logger = Logger.getLogger(getClass());
	/**
	 * 车辆基本信息缓存
	 */
	public static HashMap<Long, VehicleData> vehicleMap = new HashMap<Long, VehicleData>();

	public static ConcurrentMap<String, GPSRealData> realDataMap = new ConcurrentHashMap<String, GPSRealData>();

	/**
	 * 初始化方法，在类被创建后立即调用，将所有车辆数据读入内存的map中缓存起来
	 */
	public void initMethod() {
		try {
			String hql = "from VehicleData where deleted = ?";
			List result = vehicleDataDao.query(hql, false);
			for (Object obj : result) {
				VehicleData bd = (VehicleData) obj;
				vehicleMap.put(bd.getEntityId(), bd);
			}
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		}
	}

	@Override
	public VehicleData load(Long vehicleId) {
		if (vehicleId == 0)
			return null;
		if (vehicleMap.isEmpty())
			initMethod();
		if (vehicleMap.containsKey(vehicleId)) {
			return vehicleMap.get(vehicleId);
		}
		VehicleData vd = this.baseDao.findById(vehicleId);
		vehicleMap.put(vehicleId, vd);
		return vd;
	}

	// 获取车辆信息数据
	@Override
	public final VehicleData getVehicleByPlateNo(String plateNo) {
		String hql = "from VehicleData v where v.plateNo =  ? and deleted = ?";

		VehicleData v = this.find(hql, new Object[] { plateNo, false });
		return v;
	}

	// 获取车辆信息数据
	@Override
	public final VehicleData getVehicleBySimNo(String simNo) {
		String hql = "from VehicleData v where v.simNo =  ? and deleted = ?";

		VehicleData v = this.find(hql, new Object[] { simNo, false });
		return v;
	}

	/**
	 * 查询车辆的车辆部门
	 */
	@Override
	public Department getDepartmentByPlateNo(String plateNo) {
		VehicleData vd = this.getVehicleByPlateNo(plateNo);
		if (vd != null && vd.getDepId() > 0) {
			return departmentService.fetchDepartment(vd.getDepId());
		}
		return null;
	}

	/**
	 * 假删除车辆
	 * 
	 * @param vehicleId
	 */
	public void delete(long vehicleId, VehicleInfoModifyRecord vr) {
		this.deleteFakeById(vehicleId);
		String hsql = "from GPSRealData where vehicleId = ?";
		GPSRealData rd = this.gpsRealDataDao.find(hsql, vehicleId);
		if (rd != null) {
			this.gpsRealDataDao.delete(rd);
		}
		/**
		 * 车辆的驾驶员信息，清除关联关系，不删除；
		 */
		this.baseDao.bulkUpdate(
				"update DriverInfo set vehicleId = 0 where vehicleId = ?",
				new Object[] { vehicleId });

		this.vehicleInfoModifyRecordDao.save(vr);
	}

	/**
	 * 保存车辆信息
	 */
	@Override
	public void saveVehicleData(VehicleData vd) throws Exception {
		String hsql = "from VehicleData where (plateNo= ? or simNo = ?) and entityId <> ? and deleted = ? ";
		VehicleData otherVd = (VehicleData) baseDao.find(hsql, new Object[] {
				vd.getPlateNo(), vd.getSimNo(), vd.getEntityId(), false });
		if (otherVd != null) {
			String msg = otherVd.getPlateNo().equals(vd.getPlateNo()) ? "车牌号重复,"
					: "";
			msg += otherVd.getSimNo().equals(vd.getSimNo()) ? "卡号重复," : "";
			msg += "无法保存!";
			throw new Exception(msg);
		}
		// 更新实时表的数据
		boolean isNew = vd.getEntityId() == 0;
		if (isNew == false) {

			hsql = "from GPSRealData where vehicleId = ?";
			GPSRealData rd = gpsRealDataDao.find(hsql, vd.getEntityId());
			if (rd != null) {
				if (vd.getDeleted()) {
					gpsRealDataDao.delete(rd);
				} else {
					rd.setSimNo(vd.getSimNo());
					rd.setPlateNo(vd.getPlateNo());
					gpsRealDataDao.saveOrUpdate(rd);
				}

			}
		}
		this.baseDao.saveOrUpdate(vd);
		if (isNew) {
			// 如果是新增车辆，同时要在实时表中，新增加一条记录
			GPSRealData rd = new GPSRealData();
			rd.setVehicleId(vd.getEntityId());
			rd.setPlateNo(rd.getPlateNo());
			rd.setSimNo(rd.getSimNo());
			gpsRealDataDao.saveOrUpdate(rd);
		}
		this.vehicleMap.put(vd.getEntityId(), vd);
	}

	/**
	 * 更新车辆信息和修改记录
	 */
	@Override
	public void saveVehicleData(VehicleData vd,
			List<VehicleInfoModifyRecord> modifyRecordList) throws Exception {
		String hsql = "from VehicleData where (plateNo= ? or simNo = ?) and entityId <> ? and deleted = ? ";
		VehicleData otherVd = (VehicleData) baseDao.find(hsql, new Object[] {
				vd.getPlateNo(), vd.getSimNo(), vd.getEntityId(), false });
		if (otherVd != null) {
			String msg = otherVd.getPlateNo().equals(vd.getPlateNo()) ? "车牌号重复,"
					: "";
			msg += otherVd.getSimNo().equals(vd.getSimNo()) ? "卡号重复," : "";
			msg += "无法保存!";
			throw new Exception(msg);
		}
		boolean isNew = vd.getEntityId() == 0;
		this.baseDao.saveOrUpdate(vd);
		// 更新实时表的数据
		if (isNew == false) {
			hsql = "from GPSRealData where vehicleId = ?";
			GPSRealData rd = gpsRealDataDao.find(hsql, vd.getEntityId());
			if (rd != null && vd.getDeleted()) {
				gpsRealDataDao.delete(rd);
			} else {
				// 如果是新增车辆，同时要在实时表中，新增加一条记录
				if (rd == null)
					rd = new GPSRealData();
				rd.setVehicleId(vd.getEntityId());
				rd.setDepId(vd.getDepId());
				rd.setPlateNo(vd.getPlateNo());
				rd.setSimNo(vd.getSimNo());
				gpsRealDataDao.saveOrUpdate(rd);
			}
			hsql = "from GPSRealData where simNo = ? and vehicleId <> ?";
			List<GPSRealData> ls = gpsRealDataDao.query(hsql,
					new Object[] { vd.getSimNo(), vd.getEntityId() });
			if (ls != null) {
				for (GPSRealData r : ls) {
					gpsRealDataDao.delete(r);
				}
			}
		}
		else  {
			// 如果是新增车辆，同时要在实时表中，新增加一条记录
			GPSRealData rd = new GPSRealData();
			rd.setVehicleId(vd.getEntityId());
			rd.setDepId(vd.getDepId());
			rd.setPlateNo(vd.getPlateNo());
			rd.setSimNo(vd.getSimNo());
			gpsRealDataDao.saveOrUpdate(rd);
		}

		if (modifyRecordList.size() > 0)
			this.vehicleInfoModifyRecordDao.saveOrUpdateAll(modifyRecordList);
		this.vehicleMap.put(vd.getEntityId(), vd);
	}

	/**
	 * 根据部门id列表，查询出部门所辖车辆列表
	 */
	@Override
	public List<VehicleData> getVehicleListByDepId(List<Long> depIdList) {
		String hql = "from VehicleData where depId in (:depIdList) and deleted = 0 order by plateNo";
		if (depIdList.size() == 0) {
			depIdList.add(0L);
		}
		List<VehicleData> result = this.queryByNamedParam(hql, "depIdList",
				depIdList.toArray());
		return result;
	}

}
